use std::collections::HashSet;
use chrono::Local;
use crate::business::websocket::dto::common_dto::{ExceptionResp, OkResp};
use crate::business::websocket::dto::im_message_dto::{MessageObject};
use crate::db::dao::im_message_dao::{change_message_action_status, update_message_status};
use crate::db::dao::im_message_send_dao::{message_send_query_by_message_id, message_send_updates};
use crate::db::db::Db;
use crate::db::pojo::pojo::{ImMessage, ImMessageActionData, ImMessageActionStatus, ImMessageStatus};
use crate::db::service::im_message_service::ImMessageService;
use crate::util::const_var::MESSAGE_SPIT;

pub struct MessageReceiveService;
impl MessageReceiveService {

    pub async fn receive_message(_user_id: String, message_object: MessageObject) -> Result<OkResp, ExceptionResp> {
        let _ref_server_ids = vec![message_object].iter()
            .filter(|message_object| message_object.ref_message_ids.is_some())
            .map(|message_object| message_object.ref_message_ids.clone().unwrap())
            .flat_map(|str1| str1.split(',').map(|str2| str2.to_string()).collect::<Vec<String>>())
            .collect::<HashSet<String>>();

        todo!()
    }

    pub fn receive_read_message(user_id: &str, message_ids: HashSet<String>) -> Vec<ImMessage> {
        let mut update_message_send_list = Vec::new();
        let mut ui_update_messages = vec![];
        let mut update_message_id_set = HashSet::new();

        let db = Db::open();

        for message_id in message_ids {
            if message_id.contains(MESSAGE_SPIT) {
                let ids = message_id.split(MESSAGE_SPIT).collect::<Vec<&str>>();
                let server_id = ids[0];
                let to_user_id = ids[1].to_string();

                let message = ImMessageService::query_message_by_server_id(user_id, server_id);
                if let Some(mut message) = message {
                    if message.is_sender(user_id) {
                        let message_sends = message_send_query_by_message_id(db.clone(), message.id.unwrap());
                        let size = message_sends.len();
                        let mut readed_size = 0;
                        for mut message_send in message_sends.into_iter() {
                            if message_send.user_id == to_user_id {
                                message_send.action_status = ImMessageActionStatus::Readed;
                                message_send.update_time = Local::now();

                                update_message_send_list.push(message_send);
                                readed_size +=1;
                            } else if message_send.action_status == ImMessageActionStatus::Readed {
                                readed_size +=1;
                            }
                        }

                        if readed_size  == size {
                            message.update_date_time = Local::now();
                            message.status = ImMessageStatus::Readed;
                            message.action_status = ImMessageActionStatus::Readed;

                            update_message_status(db.clone(), message.id.unwrap(), ImMessageStatus::Readed, ImMessageActionStatus::Readed);

                            ui_update_messages.push(message);
                        }
                    } else {
                        update_message_id_set.insert(message.id.clone().unwrap());
                    }
                }

            } else {
                let message = ImMessageService::query_message_by_server_id(user_id, &message_id);

                if let Some(mut message) = message {
                    if message.is_sender(user_id) {
                        update_message_id_set.insert(message.id.clone().unwrap());

                        message.status = ImMessageStatus::Readed;
                    } else {
                        message.update_date_time = Local::now();
                        message.status = ImMessageStatus::Readed;
                        message.action_status = ImMessageActionStatus::Readed;

                        update_message_status(db.clone(), message.id.unwrap(), ImMessageStatus::Readed, ImMessageActionStatus::Readed);
                    }
                    ui_update_messages.push(message);
                }
            }
        }

        let message_action_data_list = update_message_id_set.into_iter().map(|id| ImMessageActionData {
            message_id: id,
            user_id: "".to_string(),
            action_status: ImMessageActionStatus::Readed,
        }).collect();

        change_message_action_status(db.clone(), message_action_data_list);

        message_send_updates(db.clone(), &mut update_message_send_list);

        ui_update_messages
    }
}